<template>
  <div style="margin-top: 20px">
    <el-row :gutter="10">
      <el-col :span="14">
        <el-form ref="editForm" :model="form" label-width="100px">
          <el-form-item label="数据库" prop="DbId" :rules="[{required: true, message: '请输入'}]">
            <el-select v-model="form.DbId" @change="changeDb">
              <el-option
                v-for="item in DbList"
                :key="item.ReportDbId"
                :label="item.Name"
                :value="item.ReportDbId"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="支持go模板" prop="SupportGoTemplate" :rules="[{required: true, message: '请输入'}]">
            <el-switch v-model="form.SupportGoTemplate" />
          </el-form-item>
          <el-form-item label="验证SQL并生成返回信息" prop="ValidateAndGenerateReturns" :rules="[{required: true, message: '请输入'}]">
            <el-switch v-model="form.ValidateAndGenerateReturns" />
          </el-form-item>
          <el-form-item label="SQL" prop="Sql" :rules="[{required: true, message: '请输入'}]">
            <el-row>
              <el-button icon="el-icon-s-open" title="整理SQL" size="small" @click="beautifulSql($refs.ace.$ace)" />
              <el-button icon="el-icon-lock" title="插入权限SQL" size="small" @click="insertAuthSql($refs.ace.$ace)" />
            </el-row>
            <ace-editor ref="ace" :custom-complete-data="customCompleteData" @content-change="v=>this.form.Sql=v" />
          </el-form-item>
          <el-form-item v-show="PageSupport" label="Count SQL" prop="CountSql">
            <el-row>
              <el-button title="整理SQL" size="small" icon="el-icon-s-open" @click="beautifulSql($refs.ace2.$ace)" />
              <el-button icon="el-icon-lock" title="插入权限SQL" size="small" @click="insertAuthSql($refs.ace2.$ace)" />
            </el-row>
            <ace-editor ref="ace2" :custom-complete-data="customCompleteData" @content-change="v=>this.form.CountSql=v" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="save">
              保存
            </el-button>
            <el-button @click="close">
              取消
            </el-button>
          </el-form-item>
        </el-form>
      </el-col>
      <el-col :span="5">
        <el-table
          :data="params"
          border
          fit
          highlight-current-row
          max-height="800px"
          style="width: 100%; margin-top: 20px"
        >
          <el-table-column label="属性" prop="AttributeName" />
          <el-table-column label="名称" prop="Name" />
          <el-table-column label="类型">
            <template slot-scope="scope">
              {{ scope.row.Type | dictFilter(enums.reportParamTypeEnum) }}
            </template>
          </el-table-column>
        </el-table>
      </el-col>
      <el-col :span="5">
        <el-row>
          双击插入:
          <el-switch v-model="dbClickSelect" />
          <el-button
            style="float:right"
            size="small"
            type="primary"
            @click="addTab()"
          >
            add tab
          </el-button>
        </el-row>
        <el-tabs v-model="editableTabsValue" style="margin-top: 5px" type="card" closable @tab-remove="removeTab">
          <el-tab-pane
            v-for="(item, index) in editableTabs"
            :key="item.name"
            :label="item.title"
            :name="item.name"
          >
            <table-info :index="index" :tables="Tables" @table-change="onTableChange" @column-select="onColumnSelect" />
          </el-tab-pane>
        </el-tabs>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import commonValidator from '@/utils/commonValidator'
import reportFormTypeEnum from '@/enums/report/reportFormTypeEnum'
import reportParamTypeEnum from '@/enums/report/reportParamTypeEnum'
import gql from 'graphql-tag'
import apolloClient from '@/utils/graphql'
import sqlFormatter from 'sql-formatter'
import AceEditor from '@/components/AceEditor'
import { Parser } from 'node-sql-parser'
import TableInfo from './components/table_info'
var authSqlTemplate = `
    {{if eq .auths_DataAccess 1}}
    and 1 = 1
    {{else if eq .auths_DataAccess 2}}
    and tablealiasauth_province_id = @auths_ProvinceId
    {{else if eq .auths_DataAccess 3}}
    and tablealiasauth_city_id = @auths_CityId
    {{else if eq .auths_DataAccess 4}}
    and tablealiasauth_district_id = @auths_AreaId
    {{else if eq .auths_DataAccess 5}}
    and tablealiasauth_organization_id in @auths_OrganizationIds
    {{else if eq .auths_DataAccess 6}}
    and tablealiasauth_department_id in @auths_DepartmentIds
    {{else if eq .auths_DataAccess 7}}
    and tablealiascreated_by = @auths_UserId
    {{else if eq .auths_DataAccess 8}}
    and tablealiasmanaged_by && @auths_OrganizationIds_array
    {{else}}
    and 1=2
    {{end}}
`
var orgAuthSqlTemplate = `
    {{if eq .auths_DataAccess 1}}
    and 1 = 1
    {{else if eq .auths_DataAccess 2}}
    and org.province_id = @auths_ProvinceId
    {{else if eq .auths_DataAccess 3}}
    and org.city_id = @auths_CityId
    {{else if eq .auths_DataAccess 4}}
    and org.district_id = @auths_AreaId
    {{else if eq .auths_DataAccess 5}}
    and org.organization_id in @auths_OrganizationIds
    {{else if eq .auths_DataAccess 6}}
    and org.organization_id in @auths_OrganizationIds
    {{else if eq .auths_DataAccess 7}}
    and org.organization_id in @auths_OrganizationIds
    {{else if eq .auths_DataAccess 8}}
    and org.managed_by && @auths_OrganizationIds_array
    {{else}}
    and 1=2
    {{end}}

`
export default {
  name: 'EditSql',
  components: {
    AceEditor,
    TableInfo
  },
  props: {
    // id
    id: {
      type: String,
      required: false
    }
  },
  data() {
    return {
      // 表单数据
      form: {
        DbId: null,
        Sql: null,
        CountSql: null,
        SupportGoTemplate: null,
        ValidateAndGenerateReturns: false
      },
      enums: {
        reportFormTypeEnum,
        reportParamTypeEnum
      },
      DbList: [],
      PageSupport: false,
      params: [],
      Tables: [],
      commonValidator,
      SearchColumns: [],
      Parser: new Parser(),
      dbClickSelect: false,
      editableTabsValue: '1',
      editableTabs: [{
        title: '未选择',
        name: '1',
        content: 'Tab 1 content'
      }, {
        title: '未选择',
        name: '2',
        content: 'Tab 2 content'
      }],
      nextTableName: 3
    }
  },
  computed: {
    customCompleteData() {
      var data = []
      const goIf = {}
      goIf.meta = 'GO模板'
      goIf.caption = 'if'
      goIf.value = 'if'
      goIf.score = 200
      data.push(goIf)
      const goelseIf = {}
      goelseIf.meta = 'GO模板'
      goelseIf.caption = 'else if'
      goelseIf.value = 'else if'
      goelseIf.score = 200
      data.push(goelseIf)
      const goelse = {}
      goelse.meta = 'GO模板'
      goelse.caption = 'else'
      goelse.value = 'else'
      goelse.score = 200
      data.push(goelse)
      const goEnd = {}
      goEnd.meta = 'GO模板'
      goEnd.caption = 'end'
      goEnd.value = 'end'
      goEnd.score = 200
      data.push(goEnd)
      if (this.params) {
        for (const param of this.params) {
          const item = {}
          item.meta = '参数'
          item.caption = param.AttributeName
          item.value = param.AttributeName
          item.score = 200
          data.push(item)
        }
      }

      var columns = []
      if (this.Tables) {
        for (const table of this.Tables) {
          const item = {}
          item.meta = '表'
          item.caption = table.Name
          item.value = table.Name
          item.score = 150
          data.push(item)
          var cs = []
          for (const column of table.Columns) {
            cs.push(column.Name)
            if (columns.indexOf(column.Name) >= 0) {
              continue
            }
            columns.push(column.Name)
          }
        }
      }
      for (const column of columns) {
        const item = {}
        item.meta = '列'
        item.caption = column
        item.value = column
        item.score = 120
        data.push(item)
      }
      console.log('data', data)
      return data
    }

  },
  mounted() {
    this.getDetail()
  },
  methods: {
    onTableChange(i, v) {
      this.editableTabs[i].title = v || '未选择'
    },
    onColumnSelect(c) {
      if (this.dbClickSelect) {
        this.$refs.ace.$ace.insert(c)
      }
    },
    addTab() {
      const newTabName = this.nextTableName++ + ''
      this.editableTabs.push({
        title: '未选择',
        name: newTabName
      })
      this.editableTabsValue = newTabName
    },
    removeTab(targetName) {
      const tabs = this.editableTabs
      let activeName = this.editableTabsValue
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            const nextTab = tabs[index + 1] || tabs[index - 1]
            if (nextTab) {
              activeName = nextTab.name
            }
          }
        })
      }

      this.editableTabsValue = activeName
      this.editableTabs = tabs.filter(tab => tab.name !== targetName)
    },
    insertAuthSql(t) {
      this.$prompt('请输入表名', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }).then(({ value }) => {
        if (value) {
          value = value + '.'
        }
        if (value === 'org.') {
          t.insert(orgAuthSqlTemplate)
        } else {
          var authSql = authSqlTemplate.replace(/tablealias/g, value)
          t.insert(authSql)
        }
      })
    },
    beautifulSql(t) {
      var text = t.getCopyText()
      if (!text) {
        this.$notify.error('未选中内容')
        return
      }
      t.removeWordLeft()
      let sql = text
      sql = sqlFormatter.format(sql, { indent: '\t' })
      t.insert(sql)
    },
    changeDb() {
      if (!this.form.DbId) {
        return
      }
      apolloClient.query({
        fetchPolicy: 'network-only',
        query: gql`query ($id: String!) {
                    dbTables(DbId: $id){
                        Name
                        Columns{
                            Name
                            Remark
                        }
                    }
                }`,
        variables: { id: this.form.DbId }
      }).then(response => {
        if (response.data) {
          if (response.data.dbTables) {
            this.Tables = response.data.dbTables || []
          }
        } else {
          this.$notify.error(response.errors[0].message)
        }
      }).catch((err) => {
        this.$notify.error(err.message)
      })
    },
    selectParam(row) {
      if (!this.form.Sql) {
        this.form.Sql = ''
      }
      var that = this
      this.$copyText(row.AttributeName).then(function() {
        that.$notify.success('已复制到粘贴板')
      }, function(e) {
        alert('Can not copy')
        console.log(e)
      })
    },
    getDetail() {
      apolloClient.query({
        fetchPolicy: 'network-only',
        query: gql`query ($reportId: String!) {
                    reportDetail(ReportId: $reportId){
                        SqlReport{
                            Sql
                            CountSql
                            DbId
                            SupportGoTemplate
                        }
                        ReportParams{
                            AttributeName
                            Name
                            Type
                        }
                        PageSupport
                    }
                    reportDbList{
                        ReportDbId
                        Name
                    }
                }`,
        variables: { reportId: this.id }
      }).then(response => {
        if (response.data) {
          if (response.data.reportDetail) {
            if (response.data.reportDetail.SqlReport) {
              this.form.DbId = response.data.reportDetail.SqlReport.DbId
              this.form.Sql = response.data.reportDetail.SqlReport.Sql || ''
              this.form.CountSql = response.data.reportDetail.SqlReport.CountSql || ''
              this.form.SupportGoTemplate = response.data.reportDetail.SqlReport.SupportGoTemplate || false
            }

            this.PageSupport = response.data.reportDetail.PageSupport || false
            this.params = response.data.reportDetail.ReportParams || []
            this.$refs.ace.$ace.setValue(this.form.Sql || '')
            this.$refs.ace2.$ace.setValue(this.form.CountSql || '')
          }
          if (response.data.reportDbList) {
            this.DbList = response.data.reportDbList
          }
          this.changeDb()
        } else {
          this.$notify.error(response.errors[0].message)
        }
      }).catch((err) => {
        console.log(err)
        this.$notify.error(err.message)
      })
    },
    // 保存数据
    save() {
      this.form.Sql = this.$refs.ace.$ace.getValue()
      this.$refs.editForm.validate((valid) => {
        if (valid) {
          var postData = {}
          postData.ReportId = this.id
          postData.Sql = this.form.Sql
          postData.CountSql = this.form.CountSql
          postData.DbId = this.form.DbId
          postData.SupportGoTemplate = this.form.SupportGoTemplate
          postData.ValidateAndGenerateReturns = this.form.ValidateAndGenerateReturns
          apolloClient.mutate({
            mutation: gql`mutation ($req: UpdateReportSql!) {
                            updateReportSql(Req: $req)
                        }`,
            variables: { req: postData }
          }).then(response => {
            console.log(response)
            if (response.data.updateReportSql) {
              this.$notify.success('保存成功')
              this.close()
            } else {
              this.$notify.error(response.errors[0].message)
            }
          }).catch((err) => {
            this.$notify.error(err.message)
          })
        }
      })
    },
    close() {
      this.$router.go(-1)
    }
  }
}
</script>

<style scoped>
.avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

.avatar-uploader .el-upload:hover {
    border-color: #409EFF;
}

.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
}

.avatar {
    width: 178px;
    height: 178px;
    display: block;
}
</style>
